package org.csu.chatserver.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.csu.chatserver.handlerDispatcher.HeartbeatServerHandler;
import org.csu.chatserver.coder.WebSocketFrameEncoder;
import org.csu.chatserver.handlerDispatcher.FileHandler;
import org.csu.chatserver.handlerDispatcher.WebSocketHandlerDispatcher;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


@Component
public class WebSocketServer {

    @Value("${tcp.port:9000}")
    private int port;

    @Autowired
    private ObjectProvider<WebSocketHandlerDispatcher> webSocketHandlerDispatcherProvider;

    public void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    // 发送和接受缓存区大小
                    .option(ChannelOption.SO_RCVBUF, 128 * 1024)  // 接收缓冲区128KB
                    .childOption(ChannelOption.SO_SNDBUF, 128 * 1024) // 发送缓冲区128KB
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) // 使用内存池
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(
                                    new HttpServerCodec(), // 处理 HTTP 协议
                                    new HttpObjectAggregator(65536), // 聚合 HTTP 请求
                                    new WebSocketServerProtocolHandler("/ws"), // 处理 WebSocket 握手，/chat 是路径
                                    // 添加空闲检测（避免缓冲区积压）
                                    new IdleStateHandler(30, 0, 0, TimeUnit.SECONDS),
                                    new HeartbeatServerHandler(),
                                    new WebSocketFrameEncoder(), // 自定义编码器处理文件传输
                                    new FileHandler(), // 处理文件传输
                                    webSocketHandlerDispatcherProvider.getObject() // 自定义 WebSocket 处理器
                            );
                        }
                    });
            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
